/**
 * @param {number[]} candidates
 * @param {number} target
 * @return {number[][]}
 */
var combinationSum2 = function (candidates, target) {
    let res = [];
    candidates.sort((a, b) => a - b)
    combinationSumLevel(candidates, target, [], 0, res)
    return res
};

function combinationSumLevel(nums, target, valArr, index, res) {
    let sum = 0
    for (let i = 0; i < valArr.length; i++) {
        sum += valArr[i]
    }
    if (sum === target) {
        res.push([...valArr])
        return
    }
    if (sum > target) return

    for (let i = index; i < nums.length; i++) {
        // 根节点去重，只保留相同数值的第一个
        if (i > 0 && index === 0 && nums[i] === nums[i - 1]) continue
        // 树层节点去重，只保留相同数值的第一个
        if (i > 0 && index !== i && nums[i] === nums[i - 1]) continue
        valArr.push(nums[i])
        combinationSumLevel(nums, target, valArr, i + 1, res)
        valArr.pop()
    }
}